Imports System
Imports System.Configuration
Imports System.Runtime.InteropServices

Namespace xpComponent.AutoSearch
    Public Class AutoSearching
        Implements IDisposable

        Private autoComp As Type
        Private objAutoComp As IAutoComplete

        Public Sub New(ByVal hwndEdit As IntPtr, ByVal strList As ArrayList, Optional ByVal pwszRegKeyPath As String = Nothing, Optional ByVal pwszQuickComplete As String = Nothing)
            Dim iEnumList As New EnumString
            iEnumList.strArray = strList

            autoComp = Type.GetTypeFromCLSID(New Guid("{00BB2763-6A77-11D0-A535-00C04FD7D062}"))
            objAutoComp = DirectCast(Activator.CreateInstance(autoComp), IAutoComplete)

            objAutoComp.Init(hwndEdit, iEnumList, pwszRegKeyPath, pwszQuickComplete)
            objAutoComp.SetOptions(Convert.ToUInt32(ShowOptions.ACO_AUTOSUGGEST Or ShowOptions.ACF_UPDOWNKEYDROPSLIST Or ShowOptions.ACO_AUTOAPPEND))
            objAutoComp.Enable(True)
        End Sub

        Public Sub Dispose() Implements System.IDisposable.Dispose
            Me.ReleaseComObject = Marshal.ReleaseComObject(objAutoComp)
        End Sub

        Private WriteOnly Property ReleaseComObject()
            Set(ByVal Value)
                Me.ReleaseComObject = Value
            End Set
        End Property

        Public Sub Disable()
            objAutoComp.SetOptions(Convert.ToUInt32(ShowOptions.ACO_NONE))
        End Sub

        Public Sub Enable()
            objAutoComp.SetOptions(Convert.ToUInt32(ShowOptions.ACO_AUTOSUGGEST Or ShowOptions.ACF_UPDOWNKEYDROPSLIST Or ShowOptions.ACO_AUTOAPPEND))
        End Sub
    End Class

    Public Class EnumString
        Implements UCOMIEnumString

        Public strArray As ArrayList
        Private Pos As Integer = 0

        Public Function [Next](ByVal celt As Integer, ByVal rgelt As String(), ByRef pceltFetched As Integer) As Integer Implements UCOMIEnumString.Next
            Dim retval As Integer = 1
            pceltFetched = 0
            While Not Pos = strArray.Count AndAlso Not pceltFetched = celt
                rgelt(pceltFetched) = strArray(Pos)
                pceltFetched += 1
                Pos += 1
            End While

            If Not pceltFetched.CompareTo(celt) = -1 Then
                retval = 0
            End If

            Return retval

        End Function

        Public Function Skip(ByVal celt As Integer) As Integer Implements UCOMIEnumString.Skip
            Dim retval As Integer = 1
            Pos += celt

            If Not Pos = strArray.Count Then
                retval = 0
            End If

            Return retval
        End Function

        Public Function Reset() As Integer Implements UCOMIEnumString.Reset
            Pos = 0
            Return Pos
        End Function

        Public Sub Clone(ByRef ppenum As UCOMIEnumString) Implements UCOMIEnumString.Clone
            '/// create a Clone of this Class
            ppenum = DirectCast(Me, EnumString)
        End Sub
    End Class

    Public Enum ShowOptions
        ACO_NONE = 0
        ACO_AUTOSUGGEST = &H1
        ACO_AUTOAPPEND = &H2
        ACO_SEARCH = &H4
        ACO_FILTERPREFIXES = &H8
        ACO_USETAB = &H10
        ACF_UPDOWNKEYDROPSLIST = &H20
        ACO_RTLREADING = &H40
    End Enum

    <ComImport(), InterfaceType(ComInterfaceType.InterfaceIsIUnknown), Guid("EAC04BC0-3791-11D2-BB95-0060977B464C")> _
    Public Interface IAutoComplete
        Function Init(ByVal hwndEdit As IntPtr, <MarshalAs(UnmanagedType.IUnknown)> ByVal punkACL As Object, ByVal pwszRegKeyPath As String, ByVal pwszQuickComplete As String) As Int32
        <PreserveSig()> Function Enable(<[In]()> ByVal fEnable As Boolean) As Boolean
        <PreserveSig()> Function SetOptions(<[In]()> ByVal dwFlag As UInt32) As Integer
        <PreserveSig()> Function GetOptions(<Out()> ByRef pdwFlag As UInt32) As Integer
    End Interface

    <ComImport(), InterfaceType(ComInterfaceType.InterfaceIsIUnknown), Guid("00000101-0000-0000-C000-000000000046")> _
    Public Interface IEnumString
        Function [Next](ByVal celt As Integer, ByVal rgelt() As String, ByRef pceltFetched As Integer) As Integer
        Function Skip(ByVal celt As Integer) As Integer
        Function Reset() As Integer
        Sub Clone(ByRef ppenum As IEnumString)
    End Interface
End Namespace